package com.wss.lsl.test.driven.concurrent;

import java.util.concurrent.Exchanger;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class ExchangerDemo2 {

	private static final int delay = 20;

	public static void main(String[] args) throws InterruptedException {
		System.out.println("ExchangerDemo2");
		
		Exchanger<Object> exc = new Exchanger<Object>();

		ExecutorService executorService = Executors.newCachedThreadPool();
		executorService.execute(new ExchangerProducer(exc));
		executorService.execute(new ExchangerConsumer(exc));

		TimeUnit.MILLISECONDS.sleep(delay);
		executorService.shutdownNow();
	}

	/**
	 * 生产者
	 * 
	 * @author sean
	 *
	 */
	static class ExchangerProducer implements Runnable {

		private Exchanger<Object> exc;
		private Object holder = new Object();

		public ExchangerProducer(Exchanger<Object> exc) {
			super();
			this.exc = exc;
		}

		@Override
		public void run() {
			try {
				while (!Thread.interrupted()) {
					System.out.println("ExchangerProducer before exchange:"
							+ holder);
					holder = exc.exchange(holder);
					System.out.println("ExchangerProducer after exchange:"
							+ holder);
				}
			} catch (InterruptedException e) {
				// ignore
			}
			System.out.println("exit ExchangerProducer");
		}

	}

	/**
	 * 消费者
	 * 
	 * @author sean
	 *
	 */
	static class ExchangerConsumer implements Runnable {

		private Exchanger<Object> exc;
		private Object holder = new Object();

		public ExchangerConsumer(Exchanger<Object> exc) {
			super();
			this.exc = exc;
		}

		@Override
		public void run() {
			try {
				while (!Thread.interrupted()) {
					System.out.println("ExchangerConsumer before exchange:"
							+ holder);
					holder = exc.exchange(holder);
					System.out.println("ExchangerConsumer after exchange:"
							+ holder);
				}
			} catch (InterruptedException e) {
				// ignore
			}
			System.out.println("exit ExchangerConsumer");
		}

	}

}
